/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.sourceforge.slcwsn.monitorapp;

import com.google.code.xbeejavaapi.api.XBee;
import com.google.code.xbeejavaapi.api.exception.XBeeOperationFailedException;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.util.Date;
import java.util.Iterator;
import net.sourceforge.slcwsn.event.DefaultEventVisitor;
import net.sourceforge.slcwsn.event.Event;
import net.sourceforge.slcwsn.event.LostSensorMessagesEvent;
import net.sourceforge.slcwsn.event.PIRDetectionEvent;
import net.sourceforge.slcwsn.event.SensorAliveEvent;
import net.sourceforge.slcwsn.event.SensorDiscoveredEvent;
import net.sourceforge.slcwsn.event.SensorMessageEvent;
import net.sourceforge.slcwsn.event.SuperNodeDiscoveredEvent;
import org.apache.log4j.Logger;

/**
 *
 * @author David Miguel Antunes <davidmiguel [ at ] antunes.net>
 */
public class EventLongDescriptor extends DefaultEventVisitor {

    private static final String EXCEPTION = "<!DOCTYPE html><html><head></head><body><h1>Exception</h1><br>$EXCEPTION</body></html>";
    private static final String UNIMPLEMENTED = "<!DOCTYPE html><html><head></head><body><h1>Unimplemented</h1></body></html>";
    private static final Logger logger = Logger.getLogger(EventLongDescriptor.class);
    private String description = "";

    private String getHtml(Event event) {
        try {
            String resource = "net/sourceforge/slcwsn/monitorapp/html/" + event.getClass().getSimpleName() + ".html";
            InputStream is = ClassLoader.getSystemResourceAsStream(resource);
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String html = "";
            String line;
            while ((line = br.readLine()) != null) {
                html += line + System.getProperty("line.separator");
            }
            return html;
        } catch (Exception ex) {
            logger.error(ex);
            return EXCEPTION.replace("$EXCEPTION", ex.getMessage());
        }
    }

    private String commonReplaceEvent(Event event, String html) {
        return html.replace("$TIME", DateFormat.getDateTimeInstance().format(new Date(event.getTimestamp())));
    }

    private String commonReplaceSensorEvent(SensorMessageEvent event, String html) {
        String superNodesReceived = "";
        Iterator<XBee> superNodes = event.getDetectedBy().iterator();
        try {
            if (superNodes.hasNext()) {
                superNodesReceived += superNodes.next().getNodeIdentifier();
                while (superNodes.hasNext()) {
                    superNodesReceived += "; " + superNodes.next().getNodeIdentifier();
                }
            }
        } catch (XBeeOperationFailedException ex) {
            logger.error(ex);
            superNodesReceived = "Exception";
        }
        return commonReplaceEvent(event, html).
                replace("$SEQ_NUM", "" + event.getSensorEventSequenceNumber()).
                replace("$SUPER_NODES_RECEIVED", "" + superNodesReceived).
                replace("$ID", "" + event.getSensor().getId());
    }

    public void visit(SensorDiscoveredEvent event) {
        description = commonReplaceEvent(event, getHtml(event)).
                replace("$ID", "" + event.getSensor().getId()).
                replace("$TYPE", event.getSensor().getClass().getSimpleName());
    }

    public void visit(SensorAliveEvent event) {
        description = commonReplaceSensorEvent(event, getHtml(event));
    }

    public void visit(PIRDetectionEvent event) {
        description = commonReplaceSensorEvent(event, getHtml(event));
    }

    public String getDescription() {
        return description;
    }

    public void visit(SuperNodeDiscoveredEvent event) {
        try {
            description = commonReplaceEvent(event, getHtml(event)).
                    replace("$ADDRESS", "" + event.getNode().getxBee().getSerialNumber()).
                    replace("$IDENT", "" + event.getNode().getxBee().getNodeIdentifier());
        } catch (XBeeOperationFailedException ex) {
            logger.error(ex);
            description = "Exception: " + ex.getMessage();
        }
    }

    public void visit(LostSensorMessagesEvent event) {
        description = commonReplaceEvent(event, getHtml(event)).
                replace("$N_LOST_MESG", "" + event.getnMessages()).
                replace("$ID", "" + event.getSensor().getId());
    }
}
